// 标签节点

import { touchExd } from "../TouchExtend";
import { ccs } from "../services";
import { TagNode } from "./tagsNode";
import { TouchExtend } from "../TouchExd";

const {ccclass, property, executeInEditMode, menu} = cc._decorator;

@ccclass('TagData')
export class TagData {
    @property()
    key:string = '';

    @property(cc.SpriteFrame)
    spriteFrame:cc.SpriteFrame = null;

    @property(cc.SpriteFrame)
    selectFrame:cc.SpriteFrame = null;

    @property()
    text:string = '';

    init(key:string, text:string) {
        this.key = key;
        this.text = text;
    }
}

@ccclass
@executeInEditMode
@menu('扩展组件/TagsCtrl')
export class TagsCtrl extends cc.Component {

    @property({type:ccs.LayoutType, tooltip: '布局方式：水平或者上下'})
    layoutType = ccs.LayoutType.Vertical;

    @property({type:cc.Prefab, tooltip: '未选中的标签预制'})
    normalPre: cc.Prefab = null;

    @property({type:cc.Prefab, tooltip: '选中的标签预制'})
    selectPre: cc.Prefab = null;

    @property({type:[TagData], tooltip: '标签数据'})
    tagArray: TagData[] = [];

    @property
    private _selectIdx:number = 0;
    @property({tooltip: '默认选中的序号'})
    get selectIdx() {
        return this._selectIdx;
    }
    set selectIdx(value:number) {
        this._selectIdx = value;
        this.initTagNodes();
    }

    @property
    private _spaceV:number = 0;
    @property({tooltip: '标签节点间的间隔'})
    get spaceV() {
        return this._spaceV;
    }
    set spaceV(value:number) {
        this._spaceV = value;
        this.initTagNodes();
    }

    @property({type: cc.Component.EventHandler, tooltip: '点击标签的回调函数'})
    eventHandler:cc.Component.EventHandler = null;

    @property({type: cc.Component.EventHandler, tooltip: '点击标签的是否响应的函数判断'})
    canClickHandler:cc.Component.EventHandler = null;

    @property({tooltip: '显示隐藏信息'})
    isShowHideInfo:boolean = false;

    @property({type:[cc.Node], visible(){
        return this.isShowHideInfo;
    }})
    tagNodes: cc.Node[] = [];

    @property({type:[cc.Node], visible(){
        return this.isShowHideInfo;
    }})
    tipNodes: cc.Node[] = [];

    @property({type: cc.Component, visible(){
        return this.isShowHideInfo;
    }})
    selectScript: TagNode = null;

    @property
    soundName: string = 'small_btn_click_1';

    //private _selectScript = null;
    private _isTip:boolean = false;
    private _isDefaultClick:boolean = false;
    
    start () {
        if(CC_EDITOR) {
            if(this.tagNodes.length <= 0) {
                this.initTagNodes();
            }
        } else {
            if(this.tagNodes.length <= 0) {
                this.initTagNodes();
            } else {
                for(let i = 0, len = this.tagNodes.length; i < len; i++) {
                    TouchExtend.touchEvent(this.tagNodes[i],cc.Node.EventType.TOUCH_END, this.onClickEvent, this);
                } 
            }

            if(this._isDefaultClick) {
                this._isDefaultClick = false;
                ccs.gf.doEventCallback(this.eventHandler, this.selectScript.tagData.key);
            }
        }
        
        this.setShowTip(this._isTip);
    }

    private onClickEvent(event:cc.Event.EventTouch) {
        let tagNode = event.target.getComponent(TagNode);
        if(!this.canClickHandler || (this.canClickHandler && ccs.gf.doEventCallback(this.canClickHandler, tagNode.tagData.key))) {
            this.selectNode(event.target);
            ccs.gf.doEventCallback(this.eventHandler, tagNode.tagData.key);
        }
    }

    initTagNodes() {
        this.node.destroyAllChildren();
        this.tagNodes = [];
        if(this.normalPre) {
            for(let i = 0, len = this.tagArray.length; i < len; i++) {
                let node = cc.instantiate(this.normalPre);
                this.node.addChild(node);
                if(this.layoutType == ccs.LayoutType.Vertical) {
                    node.x = 0;
                    node.y = -i * (this.normalPre.data.height + this.spaceV);
                } else {
                    node.x = i * (this.normalPre.data.width + this.spaceV);
                    node.y = 0;
                }
                node.getComponent(TagNode).setData(this.tagArray[i]);
                this.tagNodes.push(node);

                TouchExtend.touchEvent(node, cc.Node.EventType.TOUCH_END, this.onClickEvent, this);
            }
        }

        if(this.selectPre) {
            let selectNode = cc.instantiate(this.selectPre);
            this.node.addChild(selectNode);
            this.selectScript = selectNode.getComponent(TagNode);

            if(!selectNode.getComponent(cc.BlockInputEvents)) {
                selectNode.addComponent(cc.BlockInputEvents);
            }
            
            this.selectNode(this.tagNodes[this._selectIdx]);
            //sd.pf.doEventCallback(this.eventHandler, this.selectScript.tagData.key);
        }
    }

    selectKey(key:string) {
        for(let i = 0, len = this.tagNodes.length; i < len; i++) {
            if(this.tagNodes[i].getComponent(TagNode).tagData.key == key) {
                this.selectNode(this.tagNodes[i]);
                this._isDefaultClick = false;
                ccs.gf.doEventCallback(this.eventHandler, key);
            }
        } 
    }

    private selectNode(node:cc.Node) {
        if(node) {
            this.selectScript.node.setPosition(node.x, node.y);
            this.selectScript.setData(node.getComponent(TagNode).tagData);
        }
    }

    getTagNodes() {
        return this.tagNodes;
    }

    getTipNodes() {
        return this.tipNodes;
    }

    getTipNode(idx:number) {
        return this.tipNodes[idx];
    }

    private addTipNodes() {
        for(let i = 0, len = this.tagNodes.length; i < len; i++) {
            let node = this.tagNodes[i];
            let tipNode = this.tipNodes[i];
            if(!tipNode) {
                tipNode = new cc.Node();
                this.node.addChild(tipNode, 1);
                tipNode.x = node.x;
                tipNode.y = node.y;
                this.tipNodes.push(tipNode);
            }
        }
    }

    setShowTip(isShow: boolean = true) {
        this._isTip = isShow;
        if(isShow) {
            this.addTipNodes();
        }
    }

    // update (dt) {}
}
